package com.xz.xzutils.components;

import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.EditorSettings;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.codeStyle.CodeStyleManager;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;

/**
 * <p>
 *
 * </p>
 *
 * @author DONG.WANG17@HAND-CHINA.COM
 * @since 2025-01-04 22:32
 */

public class CuxEditorWrapper {
    private final String[] fileTypes = {"json","java","sql", "xml", "html", "css", "js","ts", "yaml", "properties"};
    private Editor editor;
    private String code = "";
    private String fileType = "txt";
    private Boolean isViewer = true;
    private Boolean withFileType = false;

    public CuxEditorWrapper(String code, String fileType, boolean isViewer, boolean withFileType) {
        this.code = code;
        this.fileType = fileType;
        this.isViewer = isViewer;
        this.withFileType = withFileType;
        this.editor = createEditor();
        setHeader();
    }

    public CuxEditorWrapper(String code, String fileType) {
        this.code = code;
        this.fileType = fileType;
        this.isViewer = true;
        this.withFileType = false;
        this.editor = createEditor();
    }

    public CuxEditorWrapper() {
        this.editor = createEditor();
    }

    // 格式化代码
    public static String formatCode(@NotNull String code, @NotNull String fileType) {
        FileType type = FileTypeManager.getInstance().getFileTypeByExtension(fileType);
        Project defaultProject = ProjectManager.getInstance().getDefaultProject();
        // 创建 PsiFile
        PsiFile psiFile = PsiFileFactory.getInstance(defaultProject).createFileFromText("temp." + type.getDefaultExtension(), type, code);
        // 格式化代码
        CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(defaultProject);
        codeStyleManager.reformat(psiFile);

        return psiFile.getText();
    }

    public Editor getEditor() {
        return editor;
    }

    public void setEditor(Editor editor) {
        this.editor = editor;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
        WriteCommandAction.runWriteCommandAction(null, () -> {
            this.editor.getDocument().setText(formatCode(this.code, this.fileType));
        });
    }

    public String getFileType() {
        return fileType;
    }

    public Boolean getIsViewer() {
        return isViewer;
    }

    public Boolean getWithFileType() {
        return withFileType;
    }

    private Editor createEditor() {
        // 获取文件类型管理器，并根据文件扩展名获取文件类型
        if (StringUtils.isBlank(this.fileType)) {
            this.fileType = "txt";
        }
        FileType type = FileTypeManager.getInstance().getFileTypeByExtension(this.fileType);
        // 获取编辑器工厂实例
        EditorFactory editorFactory = EditorFactory.getInstance();
        Editor editor = editorFactory.createEditor(editorFactory.createDocument(formatCode(this.code, this.fileType)), null, type, this.isViewer);
        return initEditor(editor);
    }

    public Editor initEditor(@NotNull Editor editor) {
        EditorSettings settings = editor.getSettings();

        // 设置右侧边距显示
        settings.setRightMarginShown(true);
        settings.setRightMargin(120); // 设置右侧边距为120

        // 设置空白字符显示
        settings.setWhitespacesShown(true);
        settings.setLeadingWhitespaceShown(true);
        settings.setInnerWhitespaceShown(true);
        settings.setTrailingWhitespaceShown(true);
        settings.setSelectionWhitespaceShown(true);

        // 设置软边距
        java.util.List<Integer> list = new ArrayList<>();
        list.add(150);
        list.add(180);
        settings.setSoftMargins(list);

        // 设置在达到右侧边距时换行
        settings.setWrapWhenTypingReachesRightMargin(true);

        // 设置行号显示
        settings.setLineNumbersShown(true);
        // 设置行号类型
        settings.setLineNumerationType(EditorSettings.LineNumerationType.ABSOLUTE);
        // 设置额外的行数和列数
        settings.setAdditionalLinesCount(2);
        settings.setAdditionalColumnsCount(4);
        // 设置行标记区域显示
        settings.setLineMarkerAreaShown(true);
        // 设置 gutter 图标显示
        settings.setGutterIconsShown(true);
        // 设置折叠大纲显示
        settings.setFoldingOutlineShown(true);
        // 设置自动代码折叠启用
        settings.setAllowSingleLogicalLineFolding(true);
        // 设置自动代码折叠启用
        settings.setAutoCodeFoldingEnabled(true);
        // 设置使用 Tab 字符
        settings.setUseTabCharacter(true);
        settings.setTabSize(4); // 设置 Tab 大小为4
        // 设置智能 Home 键启用
        settings.setSmartHome(true);
        // 设置虚拟空间启用
        settings.setVirtualSpace(true);
        // 设置垂直滚动偏移量和跳跃量
        settings.setVerticalScrollOffset(3);
        settings.setVerticalScrollJump(10);
        // 设置水平滚动偏移量和跳跃量
        settings.setHorizontalScrollOffset(3);
        settings.setHorizontalScrollJump(10);
        // 设置光标在 Tab 内部启用
        settings.setCaretInsideTabs(true);
        // 设置光标闪烁启用
        settings.setBlinkCaret(true);
        settings.setCaretBlinkPeriod(500); // 设置光标闪烁周期为500毫秒
        // 设置块光标启用
        settings.setBlockCursor(false);
        // 设置全行高度光标启用
        settings.setFullLineHeightCursor(true);
        // 设置光标行显示启用
        settings.setCaretRowShown(true);
        settings.setLineCursorWidth(1); // 设置光标行宽度为1
        // 设置动画滚动启用
        settings.setAnimatedScrolling(true);
        // 设置驼峰单词识别启用
        settings.setCamelWords(true);
        // 设置在底部添加额外页面启用
        settings.setAdditionalPageAtBottom(false);
        // 设置拖放功能启用
        settings.setDndEnabled(false);
        // 设置鼠标滚轮字体大小调整启用
        settings.setWheelFontChangeEnabled(true);
        // 设置鼠标点击选择是否尊重驼峰单词启用
        settings.setMouseClickSelectionHonorsCamelWords(true);
        // 设置变量内联重命名启用
        settings.setVariableInplaceRenameEnabled(true);
        // 设置避免滚动启用
        settings.setRefrainFromScrolling(false);
        // 设置缩进引导线显示启用
        settings.setIndentGuidesShown(true);
        // 设置软换行启用
        settings.setUseSoftWraps(true);
        settings.setPaintSoftWraps(true); // 设置绘制软换行启用
        // 设置自定义软换行缩进启用
        settings.setUseCustomSoftWrapIndent(true);
        settings.setCustomSoftWrapIndent(4); // 设置自定义软换行缩进为4
        // 设置单逻辑行折叠启用
        settings.setAllowSingleLogicalLineFolding(true);
        // 设置重命名预选择启用
        settings.setPreselectRename(true);
        // 设置意图灯泡显示启用
        settings.setShowIntentionBulb(false);
        // 设置语言以确定某些编辑器设置
        // settings.setLanguageSupplier(() -> Language.findLanguageByID("java"));
        // 设置特殊字符显示启用
        settings.setShowingSpecialChars(true);
        // 获取全局的编辑器颜色方案
        //EditorColorsScheme colorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
        //((EditorEx) editor).setColorsScheme(colorsScheme);
        return editor;
    }

    public void setHeader() {
        if (this.withFileType) {
            // 创建下拉框，选择文件类型
            ComboBox<String> comboBox = new ComboBox<>(fileTypes);
            comboBox.setSelectedItem(this.fileType);
            comboBox.addActionListener(e -> {
                System.out.println("Selected file type: " + comboBox.getSelectedItem());
                this.fileType = (String) comboBox.getSelectedItem();
                this.format();
            });
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(comboBox, BorderLayout.WEST);
            this.editor.setHeaderComponent(panel);
        }
    }

    public void format() {
        String text = this.editor.getDocument().getText();
        WriteCommandAction.runWriteCommandAction(null, () -> {
            this.editor.getDocument().setText(formatCode(text, this.fileType));
            this.editor.getComponent().repaint();
            this.editor.getContentComponent().repaint();
        });
    }
}
